package repositories

import (
	"errors"
	"fmt"
	"pegasus/models"
	"pegasus/utils"
	"time"

	"github.com/go-xorm/xorm"
)

//CharacterRepo 游戏人物操作
type CharacterRepo struct {
	logger utils.ILogger
	engine *xorm.Engine
}

//NewCharacterRepo 构造CharacterRepo
func NewCharacterRepo(il utils.ILogger, e *xorm.Engine) *CharacterRepo {
	return &CharacterRepo{
		logger: il,
		engine: e,
	}
}

//GetAll 获取当前用户所有的人物
func (cr *CharacterRepo) GetAll(userID int64) ([]*models.CharacterBean, error) {
	beans := make([]*models.CharacterBean, 0)
	err := utils.Transaction(cr.engine, func(si *xorm.Session) error {
		return si.Where("UserID = ?", userID).Find(&beans)
	})
	if err != nil {
		return nil, err
	}
	return beans, nil
}

//Create 创建1个用户
func (cr *CharacterRepo) Create(userID int64, name string) (int64, error) {
	bean := models.NewCharacterBean(userID, name)
	err := utils.Transaction(cr.engine, func(si *xorm.Session) error {
		_, err := si.Insert(bean)
		return err
	})
	if err != nil {
		return 0, err
	}
	return bean.ID, nil
}

//CheckValid 检测是否是合法的角色名
func (cr *CharacterRepo) CheckValid(userID int64, characterID int64) error {
	beans, err := cr.GetAll(userID)
	if err != nil {
		return err
	}

	for _, v := range beans {
		if v.ID == characterID {
			return nil
		}
	}
	return errFalse
}

//GetDetailed 获取详细信息
func (cr *CharacterRepo) GetDetailed(characterID int64) (*models.CharacterBean, error) {
	bean := &models.CharacterBean{}
	err := utils.Transaction(cr.engine, func(si *xorm.Session) error {
		found, err := si.ID(characterID).Get(bean)
		if !found {
			return fmt.Errorf("用户不存在 %d", characterID)
		}
		return err
	})
	if err != nil {
		return nil, err
	}
	return bean, nil
}

//SignIn 签到  目前只是游戏币1000
func (cr *CharacterRepo) SignIn(characterID int64) error {
	var money int64 = 1000
	bean, err := cr.GetDetailed(characterID)
	if err != nil {
		return err
	}
	return utils.Transaction(cr.engine, func(si *xorm.Session) error {
		if bean.SignInTime != nil && bean.SignInTime.After(utils.GetTodayZero()) {
			return errors.New("已经签到")
		}
		_, err := si.Insert(&models.FDSerialBean{
			FDType:      models.FDSignInGift,
			Money:       money,
			CharacterID: characterID,
		})
		if err != nil {
			return err
		}
		now := time.Now()
		bean.SignInTime = &now
		bean.Coin = bean.Coin + money
		bean.TotalSignIn = bean.TotalSignIn + 1
		_, err = si.ID(bean.ID).Cols("Coin", "TotalSignIn", "SignInTime").Update(bean)
		return err
	})
}

//SignInPeriod  目前只是游戏币10000
func (cr *CharacterRepo) SignInPeriod(characterID int64) error {
	var money int64 = 10000
	bean, err := cr.GetDetailed(characterID)
	if err != nil {
		return err
	}
	return utils.Transaction(cr.engine, func(si *xorm.Session) error {
		if bean.PeriodType == models.CharacterNormal {
			return errors.New("未购买时间卡")
		}
		if bean.PeriodSignInTime != nil && bean.PeriodSignInTime.After(utils.GetTodayZero()) {
			return errors.New("已经签到")
		}
		_, err := si.Insert(&models.FDSerialBean{
			FDType:      models.FDPeriodGift,
			Money:       money,
			CharacterID: characterID,
		})
		if err != nil {
			return err
		}
		bean.Coin = bean.Coin + money
		now := time.Now()
		bean.PeriodSignInTime = &now
		_, err = si.ID(bean.ID).Cols("Coin", "PeriodSignInTime").Update(bean)
		return err
	})
}

//Deposit 充值
func (cr *CharacterRepo) Deposit(characterID int64, gold int64) error {
	bean, err := cr.GetDetailed(characterID)
	if err != nil {
		return err
	}
	return utils.Transaction(cr.engine, func(si *xorm.Session) error {
		_, err := si.Insert(&models.FDSerialBean{
			FDType:      models.FDDeposit,
			Money:       gold,
			CharacterID: characterID,
		})
		if err != nil {
			return err
		}
		bean.Gold = bean.Gold + gold
		_, err = si.ID(bean.ID).Cols("Gold").Update(bean)
		return err
	})
}

//BuyPeriod 购买卡
func (cr *CharacterRepo) BuyPeriod(characterID int64, periodType models.CharacterPeriodType) error {
	var gold int64 = 10
	bean, err := cr.GetDetailed(characterID)
	if err != nil {
		return err
	}
	return utils.Transaction(cr.engine, func(si *xorm.Session) error {
		if bean.Gold < gold {
			return errors.New("资金不足")
		}
		if bean.PeriodType != models.CharacterNormal {
			return errors.New("已经购买时间卡")
		}
		_, err := si.Insert(&models.FDSerialBean{
			FDType:      models.FDMarket,
			Money:       -gold,
			CharacterID: characterID,
		})
		if err != nil {
			return err
		}
		bean.Gold = bean.Gold - gold
		//目前只支持月卡
		bean.PeriodType = models.CharacterMonthly
		var now = time.Now()
		bean.PeriodStartTime = &now
		var expire = now.AddDate(0, 1, 0)
		bean.PeriodExpireTime = &expire
		_, err = si.ID(bean.ID).Cols("Gold", "PeriodType", "PeriodStartTime", "PeriodExpireTime").Update(bean)
		return err
	})
}
